package com.cskaoyan.controller.admin;

import com.cskaoyan.bean.Admin;
import com.cskaoyan.bean.BaseRespVo;
import com.cskaoyan.bean.admin.vo.AdminDataVO;
import com.cskaoyan.bean.admin.vo.AdminInfoVO;
import com.cskaoyan.mapper.AuthorityMapper;
import com.cskaoyan.service.PermissionService;
import com.cskaoyan.service.RoleService;
import com.cskaoyan.shiro.MallToken;
import com.cskaoyan.utils.EncryptUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/admin/auth")
public class AuthController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private AuthorityMapper authorityMapper;

    /**
     * 管理员登录接口
     * @param map
     * @return
     */
    @RequestMapping("/login")
    public BaseRespVo login4log(@RequestBody Map map) {
        String username = (String)map.get("username");
        String password = (String)map.get("password");

        // 1.获得主体，放入客户端传过来的token
        Subject subject = SecurityUtils.getSubject();

        //UsernamePasswordToken authenticationToken = new UsernamePasswordToken(username, EncryptUtil.MD5(password));

        //给token 一个type 用于选择对应的Realm ---tangjian
        MallToken authenticationToken = new MallToken(username, EncryptUtil.MD5(password), "CustomRealm");

        // 2.用户的token认证校验
        // 过程：subject.login → 认证 → Authenticator执行认证 → realm的doGetAuthenticationInfo
        subject.login(authenticationToken);
        // 3.认证后，可以获得认证状态
        boolean authenticated = subject.isAuthenticated();
        // 4.获得用户信息 → realm里的doGetAuthenInfo中的构造的Principal信息
        Admin primaryPrincipal = (Admin) subject.getPrincipals().getPrimaryPrincipal();
        AdminDataVO adminDataVO = new AdminDataVO();
        AdminDataVO.AdminInfoBean adminInfo = new AdminDataVO.AdminInfoBean();
        adminInfo.setAvatar(primaryPrincipal.getAvatar());
        adminInfo.setNickName(username);
        adminDataVO.setAdminInfo(adminInfo);

        //token是sessionId
        adminDataVO.setToken((String) subject.getSession().getId());
        System.out.println("login请求的sessionId：" + subject.getSession().getId());

        return BaseRespVo.ok(adminDataVO);
    }

    /**
     * 管理员退出
     * @return
     */
    @PostMapping("/logout")
    public BaseRespVo logout4log() {

        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        return BaseRespVo.ok();
    }

    /**
     * 获取管理员用户信息
     * 测试地址：
     * @param token
     * @return
     */
    @RequestMapping("/info")
    public BaseRespVo info(String token) {

        Subject subject = SecurityUtils.getSubject();
//        Serializable id = subject.getSession().getId();

        // 获得主体
        Admin admin = (Admin) subject.getPrincipals().getPrimaryPrincipal();

        // 到数据库中查询用户拥有的角色名；即roleIds对应的name
        Integer[] roleArr = admin.getRoleIds();
        List<Integer> roleIds = Arrays.asList(roleArr);
        List<String> roles = roleService.queryNamesByIds(roleIds);
        // 到数据库中查询用户拥有的角色权限：根据roleIds联表查询permission
        // methodAndperms：决定前端会显示多少个选项卡
        List<String> perms = permissionService.queryPermsByRoleIds(roleIds);
        List<String> methodAndperms = new ArrayList<>();    // 这样写，如果没有角色，前端也能显示
        boolean isSuperAdmin = false;
        for (int i = 0; i < perms.size(); i++) {    // *没有对应authority表的数据，所以判断一下
            if("*".equals(perms.get(i))){
                methodAndperms.add("*");
                isSuperAdmin = true;
                break;
            }
        }
        if(!isSuperAdmin){
            methodAndperms = authorityMapper.queryApiByPerms(perms);
        }

        // 封装返回对象
        AdminInfoVO adminInfoVO = new AdminInfoVO();
        adminInfoVO.setAvatar(admin.getAvatar());   // 当前管理员头像url
        adminInfoVO.setName(admin.getUsername());   // 当前管理员账户名
        adminInfoVO.setRoles(roles);    // 当前管理员拥有的角色名数组
        adminInfoVO.setPerms(methodAndperms);    // 当前管理员拥有的权限

        return BaseRespVo.ok(adminInfoVO);
    }

}
